import { NBT } from "prismarine-nbt";
import {
    BlockPredicate,
    Entity,
    EntityAnchor,
    HeightMap,
    IntRange,
    ItemPredicate,
    Operation,
    Swizzle,
    Vec2,
    Vec3,
} from "./arguments";
import { Bool, Double, Float, Integer } from "./basic";
import { _TargetSelector } from "./selector";

export type CommandClear = {
    command: "clear";
    target?: Entity;
    item?: ItemPredicate;
    maxCount?: Integer;
};

export type CommandClone = {
    command: "clone";
    from?: string;
    to?: string;
    begin: Vec3;
    end: Vec3;
    destination: Vec3;
    method?: "replace" | "masked" | "filtered";
    handleSource?: "force" | "move" | "normal";
    filtered?: BlockPredicate;
};

export type CommandDamage = {
    command: "damage";
    target: Entity;
    amount: Float;
    damageType?: string;
    at?: Vec3;
    by?: Entity;
    from?: Entity;
};

export type CommandDeOP = {
    command: "deop";
    targets: Entity;
};

export type CommandDifficulty = {
    command: "difficulty";
    difficulty?: "easy" | "hard" | "normal" | "peaceful";
};

export type CommandEffect = {
    command: "effect";
    type: "give" | "clear";
    effect?: string;
    seconds?: Integer | "infinite";
    amplifier?: Integer;
    hideParticles?: Bool;
};

export type CommandEnchant = {
    command: "enchant";
    target: Entity;
    enchantment: string;
    level?: Integer;
};

export type CommandExecute = {
    stacks: {
        type:
            | "align"
            | "anchored"
            | "as"
            | "at"
            | "facing"
            | "in"
            | "on"
            | "positioned"
            | "rotated"
            | "summon"
            | "if";
        align?: Swizzle;
        anchored?: EntityAnchor;
        as?: Entity;
        at?: Entity;
        facing?:
            | Vec3
            | {
                  target: Entity;
                  anchor: EntityAnchor;
              };
        in?: string;
        on?:
            | "attacker"
            | "controller"
            | "leasher"
            | "origin"
            | "owner"
            | "passengers"
            | "target"
            | "vehicle";
        positioned?: {
            type: "pos" | "targets" | "height_map";
            pos?: Vec3;
            targets?: Entity;
            heightMap?: HeightMap;
        };
        rotated?: {
            type: "angle" | "targets";
            angle?: Vec2;
            targets?: Entity;
        };
        if?: {
            type:
                | "biome"
                | "block"
                | "blocks"
                | "data"
                | "dimension"
                | "entity"
                | "function"
                | "items"
                | "loaded"
                | "predicate"
                | "score";
            unless: boolean;
            biome?: {
                pos: Vec3;
                biome: string;
            };
            block?: {
                pos: Vec3;
                block: string;
            };
            blocks?: {
                start: Vec3;
                end: Vec3;
                destination: Vec3;
                type: "all" | "masked";
            };
            data?: {
                type: "block" | "entity" | "storage";
                source: string;
                path: string;
            };
            dimension?: string;
            entity?: Entity;
            function?: string;
            items?: {
                type: "block" | "entity";
                target: Vec3 | Entity;
                slot: string;
                itemPredicate: ItemPredicate;
            };
            loaded?: Vec3;
            predicate?: string;
            score?: {
                target: Entity;
                targetObjective: string;
                type: "operation" | "matches";

                operation?: Operation;
                source?: Entity;
                sourceObjective?: string;

                matches?: Integer | IntRange;
            };
            store?: {
                value: "result" | "success";
                to: {
                    type: "block" | "bossbar" | "entity" | "score" | "storage";
                    block?: {
                        pos: Vec3;
                        path: string;
                    };
                    bossbar?: {
                        id: string;
                        type: "value" | "max";
                    };
                    entity?: {
                        target: Entity;
                        path: string;
                    };
                    score?: {
                        targets: Entity;
                        objective: string;
                    };
                    storage?: {
                        target: string;
                        path: string;
                    };
                    valueType?:
                        | "int"
                        | "float"
                        | "short"
                        | "long"
                        | "double"
                        | "byte";
                    scale?: Double;
                };
            };
        };
    }[];
    run: CommandAll;
};

export type CommandExperience = {
    command: "experience";
    type: "add" | "set" | "query";
    targets: Entity;
    amount?: Integer;
    experienceType?: "levels" | "point";
};

export type CommandFill = {
    command: "fill";
    from: Vec3;
    to: Vec3;
    block: string;
    type?: "destroy" | "hollow" | "keep" | "outline" | "replace";
    replace?: BlockPredicate;
};

export type CommandFunction = {
    command: "function";
    name: string;
    argumentType?: "direct" | "block" | "entity" | "storage";
    direct?: NBT;
    block?: Vec3;
    entity?: Entity;
    storage?: string;
    path?: string;
};

export type CommandGamemode = {};

export type CommandAll = any;
